using System;
using Headspring.Training.Core.Model;
using Headspring.Training.Core.Services;
using Headspring.Training.Infrastructure.Impl;
using NHibernate;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using StructureMap;

namespace Headspring.Training.IntegrationTests
{
	[TestFixture]
	public class EmployeeRepositoryTester : DataTestBase
	{
		[Test]
		public void EmployeeShouldHaveManager()
		{
			string mgrUsername = "someUsername123643";
			var newManager = new Manager(mgrUsername, "bob", "Smith", "bobsmith@test.com",
			                             null);
			var employee = new Employee("1", "first1", "last1", "email1");

			employee.Manager = newManager;

			ISession session = getSession();

			session.SaveOrUpdate(newManager);
			session.SaveOrUpdate(employee);
			session.Flush();
			session.Dispose();

			IEmployeeRepository repository =
				ObjectFactory.FillDependencies<EmployeeRepository>();
			Employee existingEmployee = repository.GetByUserName("1");

			Assert.That(existingEmployee.Manager.Id, Is.EqualTo(newManager.Id));
		}

		[Test]
		public void ShouldFindEmployeeByUsername()
		{
			TestHelper.ClearTables();

			ISession session = getSession();
			var one = new Employee("1", "first1", "last1", "email1");
			var two = new Employee("2", "first2", "last2", "email2");
			var three = new Employee("3", "first3", "last3", "email3");
			session.SaveOrUpdate(one);
			session.SaveOrUpdate(two);
			session.SaveOrUpdate(three);
			session.Flush();
			session.Dispose();

			IEmployeeRepository repository =
				ObjectFactory.FillDependencies<EmployeeRepository>();
			Employee employee = repository.GetByUserName("1");
			Assert.That(employee.Id, Is.EqualTo(one.Id));
		}

		[Test]
		public void ShouldGetAllEmployees()
		{
			TestHelper.ClearTables();

			ISession session = getSession();
			var one = new Employee("1", "first1", "last1", "email1")
			          	{PasswordHash = "hash1", PasswordSalt = "salt1"};
			var two = new Employee("2", "first2", "last2", "email2")
			          	{PasswordHash = "hash2", PasswordSalt = "salt2"};
			var three = new Employee("3", "first3", "last3", "email3")
			            	{PasswordHash = "hash3", PasswordSalt = "salt3"};
			session.SaveOrUpdate(two);
			session.SaveOrUpdate(three);
			session.SaveOrUpdate(one);
			session.Flush();
			session.Dispose();

			IEmployeeRepository repository =
				ObjectFactory.FillDependencies<EmployeeRepository>();
			Employee[] employees = repository.GetAllEmployeesSorted();

			Assert.That(employees.Length, Is.EqualTo(3));
			Assert.That(employees[0].UserName, Is.EqualTo("1"));
			Assert.That(employees[0].FirstName, Is.EqualTo("first1"));
			Assert.That(employees[0].LastName, Is.EqualTo("last1"));
			Assert.That(employees[0].EmailAddress, Is.EqualTo("email1"));
			Assert.That(employees[0].PasswordHash, Is.EqualTo("hash1"));
			Assert.That(employees[0].PasswordSalt, Is.EqualTo("salt1"));
		}


		[Test]
		public void ShouldSaveManager()
		{
			string username = "someUsername123643";
			var secretary = new Secretary("secret1", "some", "secretary",
			                              "some@secretary.com");
			var newManager = new Manager(username, "bob", "Smith", "bobsmith@test.com",
			                             secretary);
			ISession session = getSession();

			session.SaveOrUpdate(secretary);
			session.SaveOrUpdate(newManager);
			session.Flush();
			session.Dispose();

			IEmployeeRepository repository =
				ObjectFactory.FillDependencies<EmployeeRepository>();
			Employee savedEmployee = repository.GetByUserName(username);

			Assert.That(savedEmployee, Is.InstanceOfType(typeof (Manager)));
			Assert.That(savedEmployee.UserName, Is.EqualTo(username));
		}

		[Test]
		public void ShouldSaveSecretary()
		{
			string username = "someUsername123643";
			var secretary = new Secretary(username, "bob", "Smith", "bobsmith@test.com");
			secretary.AddEmailPreference(DayOfWeek.Friday, "somesecretary@footest.com");

			ISession session = getSession();
			session.SaveOrUpdate(secretary);
			session.Flush();
			session.Dispose();

			IEmployeeRepository repository =
				ObjectFactory.FillDependencies<EmployeeRepository>();
			Employee savedSecretary = repository.GetByUserName(username);

			Assert.That(savedSecretary, Is.InstanceOfType(typeof (Secretary)));
			Assert.That(secretary.GetEmailPreferences()[DayOfWeek.Friday],
			            Is.EqualTo("somesecretary@footest.com"));
		}
	}
}